The Let's Play Archive

SHENZHEN I/O

by Quackles

Part 62: Assignment #30: Airline Cocktail Mixer

Airline Cocktail Mixer



This sound like an interesting idea. Useful, too. I wonder if this would be aimed more at first class or coach travelers? Mind you, if you're flying in super-mega first class, you've probably got your own private bartender, but this seems like it'd do the job across the board otherwise.
(As a side note, Carl's not wrong. See? Joe has sobered up.)







Looking at the spec, it's pretty simple. Get the number from the keypad, output a pattern of matching pulses that matches the recipe from the book:



The way the nozzles are set up turns "1 oz" into 2 time units, "1.5 oz" into 3, "2 oz" into 4 time units, and "3 oz" into 6. For those wondering, the spec is set up such that the machine should dispense any liquor (vodka or gin) and mixer (lemon, lime, cranberry, vermouth) at the same time - it can't dispense them one after the other.



Effectively, this is the big brother of the meat printer from earlier, and I might be able to solve it the same way: with logic gates. My first attempt is going to definitely be using logic gates, in order to save as much power and (hopefully) cost as possible. Worst case, I'll have to use a PGA33X6 instead, or ditch the gates and put the drink-serving conditional logic in software. But for now: Logic ahoy!

(PS before we start: Aren't those lines in the book corny? I didn't know the thing about the cranberries craneberries, though.)

[ ~ ]

My mental blueprint for the logic gate versions was as follows:
[1] Get a MC.
[2] Hook that MC up to a memory chip so that it can output 3-line patterns (one for each drink), with the help of an expander.
[3] On receiving an input, turn on the vodka (or gin) output, and pull the appropriate pattern from the memory chip and push it to the expander. (The expander will be connected to the logic gates, which'll go to the mixer outputs.)
[4] Wait the right amount of time for the mixers, then turn off the mixer output. Then wait more, then turn off the liquor output. Done!

So, I created a setup that did just that. The only problem ended up being the amount of space left for the logic gates:





   

The top MC listens to the keypad and outputs the 'vodka' or 'gin' pattern to the top expander. Then it passes the keypad value onto the lower MC, which reads the right output pattern from the memory chip (the patterns aren't in yet - I can't know what to put without wiring up the logic gates first) and outputs it to the lower expander, which should connect to the outputs via the gates.

The pattern of gates I came up with required four AND gates and a NOT gate - you can see them in the pics above. The gates were to be wired up to the lower expander as listed:
Lemon  =  P2 AND ~P1 (the ~ means NOT, so ~P1 means P1 is off.)
Lime  =  P2 AND P1
Cranberry  =  P0 AND P1
Vermouth  =  P0 AND ~P1

This would let an output of [1,0,0] dispense lemon, an output of [1,1,0] dispense lime, an output of [0,1,1] dispense cranberry, an output of [1,1,1] dispense both lime and cranberry, and an output of [0,0,1] dispense vermouth. The only problem is that I played around with the gates, and I am very sure that four large, square AND gates (plus wires) won't fit.

Which brings me to my actual solution:





     

It's basically the exact same design, but the logic gate section has been redone, with most of the gates replaced by a PGA33X6. I also got a bit clever - since the PGA is three-inputs-to-three-outputs only, and we have four mixer outputs, I had to base the fourth output on something, and the fact that cranberry is only used by vodka-containing drinks made it easier. (Also, this pattern setup saves some power with the PGA, compared to connecting to cranberry to P0 AND P1.)

The logic setup, from both the PGA and the AND gate, is now as follows:

Lemon  =  P2 AND ~P1
Lime  =  P2 AND P1
Cranberry  =  'vodka' AND P1
Vermouth  =  P0 AND ~P1

An output of [1,0,0] dispenses lemon, an output of [1,1,0] dispenses lime, an output of [0,1,0] dispenses cranberry if 'vodka' is on ([1,1,0] with 'vodka' on will dispense both lime and cranberry), and an output of [0,0,1] dispenses vermouth.

(There's a few more things about the memory chip I should explain before wrapping up this section. The numbers in the chip in between the patterns are timers - they tell the device how long to dispense just the liquor after stopping the mixer outputs.
The other thing is that, though the pattern-timer pairs are in order by drink, they actually start two cells down from the top left and wrap around, instead of beginning at the top. The reason for this is that the keypad's number is multiplied by 2 and used to pull an address from the memory chip - and 1*2 = cell 2 [two down from the top left], while 7*2 = cell 14 [which wraps around to 0].)

The whole contraption is ¥16, and uses 207 power on average, but I'm not happy with it. Mostly, this is due to the presence of the PGA33X6. Logic gates may not have fit, but I haven't tried creating the conditional logic entirely in software (in MCs) yet. I suspect it might be simpler and less power-intensive - and this device is meant to be used by flight attendants on airplanes, so it'll almost certainly be running on an internal battery. Power usage is more of a concern than cost at this point.

Which means my next job is to completely throw out this design and write a lot of MC code.

[ ~ ~ ]

It took some figuring out and writing down patterns, but here's what I came up with:



   

This design throws 'clever' out the window in exchange for 'straightforward'. The leftmost MC is responsible for reading from the keypad and deciding whether to turn on the vodka or gin outputs - and for how long (3, 4, or 6 time units). It then passes the keypad number to the small MC in the middle.
The middle MC has one job - if the keypad value is for a martini (5 or 7), it pulses the vermouth output for 2 time units. Otherwise, it passes the keypad value along to the far right MC, which handles the rest of the mixers.
The rightmost MC is mostly just a series of conditional statements. Each checks the keypad value against a specific drink order, and turns on lemon, lime, and/or cranberry in combination - then turns them off after 2 (or 4) time units.
I was able to improve on the PGA version a bit with this one. This prototype is ¥14, and uses 191 power on average. Unless I can come up with something better (or better-optimized) in some way, that looks to be as good as it'll get.

I'm going to take a bit of a coffee break before I send this version in. Just in case.

[ ~ ~ ~ ]

I FIGURED IT OUT!
The basic idea took three minutes. It took a solid day, including writing a Python program connected to the Espresso boolean-logic minimizer library, to figure out the rest.

The nub is: it looks like the logic-gate version will always require 5 logic gates. (This is part of what the Python program was there to check.) But— what if the logic gates were three ANDs and two NOTS, instead of four ANDs and one NOT? That could fit, right?
It turns out (after a lot of testing, trying, and sorting through my program's output possibilities) that it all fits perfectly.





   


Key changes to the design include:
The upper output expander got moved over to the far right, meaning I only need to run one output line across the top instead of two. The extra space was used for logic gates.
The lower MC and memory chip have had their positions swapped, which means I can wire them to take up less space (the middle chip, now the memory chip, doesn't stick out as far right as much as the lower MC did when it was there.)
And, of course, the logic gates have been revamped.

The new logic gate setup is as follows:

Lemon  =  P1 AND ~P2 (remember, ~ is NOT.)
Cranberry  =  P0
Vermouth  =  ~P1 and P2
Lime  =  This'll take some explaining. On the face of it, it's P1 AND ~Lemon. But, Lemon is P1 AND ~P2, so ~Lemon could be any of: (~P1 AND ~P2), (~P1 AND P2), (P1 AND P2).
This is where the fact that both AND gates use P1 as an input comes in handy. The only ~Lemon combination that has P1 on and will work for the Lime gate is P1 AND P2 - which makes it the only combination that turns on the Lime output. Effectively, the whole point of chaining the AND gates was because I couldn't get separate wires for P1 and P2 to fit.

For reference, [0,1,0] dispenses lemon, [1,1,0] dispenses lime, [0,0,1] dispenses cranberry, [1,1,1] dispenses lime and cranberry, and [1,0,0] dispenses vermouth. The patterns in the memory chip are updated to match.

So, the new and improved version... is ¥15 - slightly more expensive than the three-MC version. However, it is more power-efficient, needing only 142 units of power, on average, per run. I'm so happy I could get logic gates working! And I got the power usage down, which is the most important thing.

Now, time for one last once-over, and then it's going out.

[ ~ ~ ~ ~ ]





   

I had one last idea on how to improve the design. I think this is it. It's as perfect as it can get. The difference between this version and the last one is: I realized that I could repeat the 'chaining AND gates' thing to cut the NOT gates out from the picture entirely.

Here's how it works. We have the following pattern of outputs:

Output A  =  P1 AND P2
Output B  =  P1 AND ~P2
Output C  =  ~P1 AND P2

(I'm using "Output A-C" because I shuffled the patterns around again to make this work. I'll detail the actual mixer output assignments at the end.)
Basically, each possible combination of P1 and P2 codes for a different output (except P1 and P2 both off, which codes for 'everything off'). And I can use the inverted output of an AND gate to see when its condition isn't met. So, if I have an AND gate for P1 AND P2, I can use its inverted output almost like an XOR gate, kind of.

Output A  =  P1 AND P2
NOT Output A  =  (~P1 AND P2) or (P1 AND ~P2) or (~P1 AND ~P2 aka 'all off')

But, if I want to use the inverted output from the Output A AND gate, I have to be able to distinguish between the three situations I listed. I can do that by piping ~A and one other input into a new AND gate. And that's what I do.

Output A  =  P1 AND P2
Output B  =  ~A AND P1  =  P1 AND ~P2
Output C  =  ~A AND P2  =  ~P1 AND P2

The NOT gates are still technically "in" the circuit - they're just part of the first AND now. Which means I can wire everything up like so:

Lemon  =  ~P1 AND P2
Lime  =  P1 AND P2
Cranberry  =  P0
Vermouth  =  P1 AND ~P2

[1,0,0] dispenses lemon, [1,1,0] dispenses lime, [0,0,1] dispenses cranberry, [1,1,1] dispenses lime and cranberry, and [0,1,0] dispenses vermouth. The final product has the same power usage as before (142), but is now only ¥13.

And that's it. Joe's dream is now a reality, corny lines (not!) and all. I think it'll do pretty well, honestly. It's labor-saving and fulfills a defined purpose...
I guess Joe's finally made it to the big time.



Honestly, I'm glad everything turned out OK with the guy. I mean, Joe could be an annoying person at times, and there’s no denying he had more harebrained schemes than an actual hare, but he's changed, and... well, everyone loves a happy ending.

(Bonus: There's no way Joe was inviting Mr. Yonghong to dinner. Was this email intended for Lili? )